package com.wisnews.controller.sr;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.wisnews.config.aspectjLog.AopVisitLog;
import com.wisnews.pojo.Input;
import com.wisnews.pojo.Result;
import com.wisnews.pojo.sr.entity.Member;
import com.wisnews.pojo.sr.vo.MemberLoginVO;
import com.wisnews.service.Impl.QQEmailService;
import com.wisnews.service.sr.Impl.MemberServiceImpl;
import com.wisnews.util.Constants;
import com.wisnews.util.DateUtil;
import com.wisnews.util.ShiroUtil;
import com.wisnews.util.TableDateFormat;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * @Description：
 * @Author: yuyd
 * @Email: yyd8358@foxmail.com
 * @Date: 2021/2/2 15:35
 * @Version 1.0
 */
@RestController
@RequestMapping("/member")
@Slf4j
public class MemberController {
    @Autowired
    private MemberServiceImpl memberService;
    @Autowired
    @Qualifier("sendEmail")
    private QQEmailService sendEmail;

    /**
     * @description: 前台简单登录认证
     * @param:
     * @return:
     * @author yuyd
     * @date: 2021/3/31 17:06
     */
    @RequestMapping(value = "simpleLogin",method = RequestMethod.POST)
    public Result memberLogin(@RequestBody MemberLoginVO loginVO, HttpServletRequest request){

        HttpSession session = request.getSession();

        if (StringUtils.isBlank(loginVO.getUsername()) || StringUtils.isBlank(loginVO.getPassword())){
            return new Result(Constants.SYS_CODE.FAIL, Constants.SYS_CODE.FAIL_MESSAGE);
        }

        //加密处理，简单md5 加密算法加密
        String password = ShiroUtil.simpleEncrypt(loginVO.getPassword());

        LambdaQueryWrapper<Member> lambdaQueryWrapper = Wrappers.lambdaQuery();
        Member one = memberService.getOne(lambdaQueryWrapper.eq(Member::getUserLoginCode,loginVO.getUsername()).or().eq(Member::getUserEmail,loginVO.getUsername()));
        if (ObjectUtils.isNotNull(one) &&  password.equals(one.getUserPasswd())){
            //后台传统方式获取，将前台用户信息存入会话session
            session.setAttribute("member",one);
            //发送登录提示邮件
            String ipAddr = AopVisitLog.getIpAddr(request);
            String context = new StringBuilder("亲爱的智慧新闻会员,您的账户在IP：").append(ipAddr)
                    .append("登录！（").append(DateUtil.getCurrentDateTime()).append("）如非本人操作请尽快修改密码。本人操作请忽略。").toString();
            sendEmail.sendSimpleMail(one.getUserEmail(),"智慧新闻会员登录提醒",context);

            return new Result(Constants.SYS_CODE.SUCCESS, Constants.SYS_CODE.SUCCESS_MESSAGE,one);
        }


        return new Result(Constants.SYS_CODE.FAIL, Constants.SYS_CODE.FAIL_MESSAGE);
    }


    /**
     * @description: 前台用户shiro 登录认证
     * @param: 登录vo
     * @return: result
     * @author yuyd
     * @date: 2021/3/31 17:06
     */
    @RequestMapping(value = "login",method = RequestMethod.POST)
    public Result shiroLogin(@RequestBody MemberLoginVO memberLoginVO){

        //获取安全管理类
        Subject subject = SecurityUtils.getSubject();

        if (StringUtils.isBlank(memberLoginVO.getUsername()) || StringUtils.isBlank(memberLoginVO.getPassword())){
            return new Result(Constants.SYS_CODE.FAIL, Constants.SYS_CODE.FAIL_MESSAGE);
        }
        Result result = new Result(Constants.SYS_CODE.SUCCESS, Constants.SYS_CODE.SUCCESS_MESSAGE);

        UsernamePasswordToken token = new UsernamePasswordToken(memberLoginVO.getUsername(),memberLoginVO.getPassword());
        try {
            subject.login(token);
            //认证成功 ,认证失败不会往下执行,认证失败抛出异常
            Session session = subject.getSession();
            Member principal = (Member)subject.getPrincipal();
            //前台用户存入缓存
            session.setAttribute(Constants.SYS_CODE.HOME_USER,principal);
            //设置超时时间
            session.setTimeout(Constants.SYS_CODE.maxIdleTimeInMillis);
        } catch (UnknownAccountException e) {
            result.setCode(Constants.SYS_CODE.FAIL);
            result.setMsg("用户名不存在或密码错误");
        } catch (IncorrectCredentialsException e) {
            result.setCode(Constants.SYS_CODE.FAIL);
            result.setMsg("用户名不存在或密码错误");
        } catch (Exception e) {
            result.setCode(Constants.SYS_CODE.FAIL);
            result.setMsg("系统异常请联系管理员:" + e.toString());
        }

        return result;
    }

    /**
     * @description: 注册
     * @param: member
     * @return: result
     * @author yuyd
     * @date: 2021/2/31 17:07
     */
    @RequestMapping(value = "register",method = RequestMethod.POST)
    public Result registerMember(@RequestBody Member member){

        LambdaQueryWrapper<Member> lambdaQueryWrapper = Wrappers.lambdaQuery();
        if (StringUtils.isBlank(member.getUserLoginCode())){
            return new Result(Constants.SYS_CODE.FAIL, Constants.SYS_CODE.FAIL_MESSAGE);
        }
        Member one = memberService.getOne(lambdaQueryWrapper.eq(Member::getUserLoginCode,member.getUserLoginCode()));
        if (ObjectUtils.isNotNull(one)){
            return new Result(Constants.SYS_CODE.FAIL,"用户名不可用");
        }
        lambdaQueryWrapper.clear();

        if (StringUtils.isBlank(member.getUserEmail())){
            return new Result(Constants.SYS_CODE.FAIL, Constants.SYS_CODE.FAIL_MESSAGE);
        }
        Member queryMember = memberService.getOne(lambdaQueryWrapper.eq(Member::getUserEmail, member.getUserEmail()));

        if (ObjectUtils.isNotNull(queryMember)){
            return new Result(Constants.SYS_CODE.FAIL,"邮箱不可用");
        }
        //密码加密处理
        String userPasswd = member.getUserPasswd();
        member.setUserPasswd(ShiroUtil.simpleEncrypt(userPasswd));
        //保存用户
        memberService.save(member);
        return new Result(Constants.SYS_CODE.SUCCESS, Constants.SYS_CODE.SUCCESS_MESSAGE);
    }

    /**
     * @description: 返回前台会员列表 需要资源访问权限，sys:update权限 通过 请求权限控制表，无感控制。
     * @param: 查询分页参数 input
     * @return: resutl
     * @author yuyd
     * @date: 2021/2/31 17:08
     */
    @RequestMapping(value = "list",method = RequestMethod.POST)
    public TableDateFormat memberList(@RequestBody Input<Member> input){
        log.error("入参"+input);
        IPage<Member> members = memberService.getListForInput(input.toPage(),input.getReq());
        TableDateFormat userList = new TableDateFormat();
        userList.setCode(0);
        userList.setMsg("数据加载成功！");
        userList.setCount((int) members.getTotal());
        userList.setData(members.getRecords());
        return userList;
    }

}
